/*! 
 * Interface file for a triangle shape (used for complex meshes like terrains).
 *
 * \author Devis Rossini
 * \date 16 April 2012
 */
#ifndef PHXTRIANGLE_H_INCLUDE_GUARD
#define PHXTRIANGLE_H_INCLUDE_GUARD

#include "PhxCore.h"
#include "PhxMaterial.h"

namespace phx
{
	struct TriangleVertex
	{
		//! Costructor.
		TriangleVertex() { }

		//! Costructor.
		TriangleVertex(const Vector3& iVertex, const Material& iMaterial) 
			: mVertex(iVertex), mMaterial(iMaterial) { }

		/*!< Triangle vertex coordinates. */
		Vector3 mVertex;

		/*!< Material of the vertex. */
		Material mMaterial;
	};

	class Triangle
	{
	private:

		TriangleVertex mTriangleVertex0;	/*!< Triangle vertex #1. */ 
		TriangleVertex mTriangleVertex1;	/*!< Triangle vertex #2. */
		TriangleVertex mTriangleVertex2;	/*!< Triangle vertex #3. */

		Vector3 mNormal;					/*!< Triangle normal. */

		Vector3 CalculateNormal();

	public:

		//! Costructor.
		Triangle() { }

		//! Costructor.
		Triangle(	const TriangleVertex& iTriangleVertex0, 
			const TriangleVertex& iTriangleVertex1, 
			const TriangleVertex& iTriangleVertex2)
			:	mTriangleVertex0(iTriangleVertex0), 
			mTriangleVertex1(iTriangleVertex1), 
			mTriangleVertex2(iTriangleVertex2), 
			mNormal(CalculateNormal()) { }

		//! Costructor.
		Triangle(	const Vector3& iVertex0,
			const Vector3& iVertex1,
			const Vector3& iVertex2,
			const Material& iMaterial0,
			const Material& iMaterial1,
			const Material& iMaterial2)
			:	mTriangleVertex0(iVertex0, iMaterial0),
			mTriangleVertex1(iVertex1, iMaterial1),
			mTriangleVertex2(iVertex2, iMaterial2),
			mNormal(CalculateNormal()) { }

		/*!
		Normal.
		*/
		Vector3 GetNormal() const;

		/*!
		Vertex0.
		*/
		Vector3 GetVertex0() const;

		/*!
		Vertex1.
		*/
		Vector3 GetVertex1() const;

		/*!
		Vertex2.
		*/
		Vector3 GetVertex2() const;

		/*!
		Project a given point on the triangle's plane.
		*/
		Vector3 PointProjectionOnPlane(const Vector3&) const;

		/*!
		Check if the projection of a point belongs to the triangle.
		*/
		bool IsProjectionInTriangle(const Vector3&) const;
	};
}

#endif // PHXTRIANGLE_H_INCLUDE_GUARD